package pe.edu.upc.e41a.javasoft.jsf;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.faces.application.Application;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.component.html.HtmlOutputText;
import javax.faces.component.html.HtmlPanelGrid;
import javax.faces.context.FacesContext;
import javax.faces.validator.LengthValidator;
import org.primefaces.component.autocomplete.AutoComplete;
import org.primefaces.component.inputtext.InputText;
import org.primefaces.component.inputtextarea.InputTextarea;
import org.primefaces.component.message.Message;
import org.primefaces.context.RequestContext;
import org.primefaces.event.CloseEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.roo.addon.jsf.managedbean.RooJsfManagedBean;
import org.springframework.roo.addon.serializable.RooSerializable;
import pe.edu.upc.e41a.javasoft.domain.Categoria;
import pe.edu.upc.e41a.javasoft.domain.Publicacion;
import pe.edu.upc.e41a.javasoft.jsf.converter.CategoriaConverter;
import pe.edu.upc.e41a.javasoft.service.CategoriaService;

@Configurable
@ManagedBean(name = "categoriaBean")
@SessionScoped
@RooSerializable
@RooJsfManagedBean(entity = Categoria.class, beanName = "categoriaBean")
public class CategoriaBean implements Serializable {

	private static final long serialVersionUID = 1L;

	@Autowired
    CategoriaService categoriaService;

	private String name = "Categorias";

	private Categoria categoria;

	private List<Categoria> allCategorias;

	private boolean dataVisible = false;

	private List<String> columns;

	private HtmlPanelGrid createPanelGrid;

	private HtmlPanelGrid editPanelGrid;

	private HtmlPanelGrid viewPanelGrid;

	private boolean createDialogVisible = false;

	private List<Publicacion> selectedPublicacions;

	private List<Categoria> selectedCategorias;

	@PostConstruct
    public void init() {
        columns = new ArrayList<String>();
        columns.add("nombre");
        columns.add("descripcion");
    }

	public String getName() {
        return name;
    }

	public List<String> getColumns() {
        return columns;
    }

	public List<Categoria> getAllCategorias() {
        return allCategorias;
    }

	public void setAllCategorias(List<Categoria> allCategorias) {
        this.allCategorias = allCategorias;
    }

	public String findAllCategorias() {
        allCategorias = categoriaService.findAllCategorias();
        dataVisible = !allCategorias.isEmpty();
        return null;
    }

	public boolean isDataVisible() {
        return dataVisible;
    }

	public void setDataVisible(boolean dataVisible) {
        this.dataVisible = dataVisible;
    }

	public HtmlPanelGrid getCreatePanelGrid() {
        if (createPanelGrid == null) {
            createPanelGrid = populateCreatePanel();
        }
        return createPanelGrid;
    }

	public void setCreatePanelGrid(HtmlPanelGrid createPanelGrid) {
        this.createPanelGrid = createPanelGrid;
    }

	public HtmlPanelGrid getEditPanelGrid() {
        if (editPanelGrid == null) {
            editPanelGrid = populateEditPanel();
        }
        return editPanelGrid;
    }

	public void setEditPanelGrid(HtmlPanelGrid editPanelGrid) {
        this.editPanelGrid = editPanelGrid;
    }

	public HtmlPanelGrid getViewPanelGrid() {
        if (viewPanelGrid == null) {
            viewPanelGrid = populateViewPanel();
        }
        return viewPanelGrid;
    }

	public void setViewPanelGrid(HtmlPanelGrid viewPanelGrid) {
        this.viewPanelGrid = viewPanelGrid;
    }

	public HtmlPanelGrid populateCreatePanel() {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        Application application = facesContext.getApplication();
        ExpressionFactory expressionFactory = application.getExpressionFactory();
        ELContext elContext = facesContext.getELContext();
        
        HtmlPanelGrid htmlPanelGrid = (HtmlPanelGrid) application.createComponent(HtmlPanelGrid.COMPONENT_TYPE);
        

        
        HtmlOutputText padreCreateOutput = (HtmlOutputText) application.createComponent(HtmlOutputText.COMPONENT_TYPE);
        padreCreateOutput.setId("padreCreateOutput");
        padreCreateOutput.setValue("Padre:   ");
        htmlPanelGrid.getChildren().add(padreCreateOutput);
        
        AutoComplete padreCreateInput = (AutoComplete) application.createComponent(AutoComplete.COMPONENT_TYPE);
        padreCreateInput.setId("padreCreateInput");
        padreCreateInput.setValueExpression("value", expressionFactory.createValueExpression(elContext, "#{categoriaBean.categoria.padre}", Categoria.class));
        padreCreateInput.setCompleteMethod(expressionFactory.createMethodExpression(elContext, "#{categoriaBean.completePadre}", List.class, new Class[] { String.class }));
        padreCreateInput.setDropdown(true);
        padreCreateInput.setValueExpression("var", expressionFactory.createValueExpression(elContext, "padre", String.class));
        padreCreateInput.setValueExpression("itemLabel", expressionFactory.createValueExpression(elContext, "#{padre.nombre} #{padre.descripcion}", String.class));
        padreCreateInput.setValueExpression("itemValue", expressionFactory.createValueExpression(elContext, "#{padre}", Categoria.class));
        padreCreateInput.setConverter(new CategoriaConverter());
        padreCreateInput.setRequired(false);
        htmlPanelGrid.getChildren().add(padreCreateInput);
        
        Message padreCreateInputMessage = (Message) application.createComponent(Message.COMPONENT_TYPE);
        padreCreateInputMessage.setId("padreCreateInputMessage");
        padreCreateInputMessage.setFor("padreCreateInput");
        padreCreateInputMessage.setDisplay("icon");
        htmlPanelGrid.getChildren().add(padreCreateInputMessage);
        
        HtmlOutputText nombreCreateOutput = (HtmlOutputText) application.createComponent(HtmlOutputText.COMPONENT_TYPE);
        nombreCreateOutput.setId("nombreCreateOutput");
        nombreCreateOutput.setValue("Nombre: * ");
        htmlPanelGrid.getChildren().add(nombreCreateOutput);
        
        InputText nombreCreateInput = (InputText) application.createComponent(InputText.COMPONENT_TYPE);
        nombreCreateInput.setId("nombreCreateInput");
        nombreCreateInput.setValueExpression("value", expressionFactory.createValueExpression(elContext, "#{categoriaBean.categoria.nombre}", String.class));
        LengthValidator nombreCreateInputValidator = new LengthValidator();
        nombreCreateInputValidator.setMaximum(20);
        nombreCreateInput.addValidator(nombreCreateInputValidator);
        nombreCreateInput.setRequired(true);
        htmlPanelGrid.getChildren().add(nombreCreateInput);
        
        Message nombreCreateInputMessage = (Message) application.createComponent(Message.COMPONENT_TYPE);
        nombreCreateInputMessage.setId("nombreCreateInputMessage");
        nombreCreateInputMessage.setFor("nombreCreateInput");
        nombreCreateInputMessage.setDisplay("icon");
        htmlPanelGrid.getChildren().add(nombreCreateInputMessage);
        
        HtmlOutputText descripcionCreateOutput = (HtmlOutputText) application.createComponent(HtmlOutputText.COMPONENT_TYPE);
        descripcionCreateOutput.setId("descripcionCreateOutput");
        descripcionCreateOutput.setValue("Descripcion: * ");
        htmlPanelGrid.getChildren().add(descripcionCreateOutput);
        
        InputTextarea descripcionCreateInput = (InputTextarea) application.createComponent(InputTextarea.COMPONENT_TYPE);
        descripcionCreateInput.setId("descripcionCreateInput");
        descripcionCreateInput.setValueExpression("value", expressionFactory.createValueExpression(elContext, "#{categoriaBean.categoria.descripcion}", String.class));
        LengthValidator descripcionCreateInputValidator = new LengthValidator();
        descripcionCreateInputValidator.setMaximum(100);
        descripcionCreateInput.addValidator(descripcionCreateInputValidator);
        descripcionCreateInput.setRequired(true);
        htmlPanelGrid.getChildren().add(descripcionCreateInput);
        
        Message descripcionCreateInputMessage = (Message) application.createComponent(Message.COMPONENT_TYPE);
        descripcionCreateInputMessage.setId("descripcionCreateInputMessage");
        descripcionCreateInputMessage.setFor("descripcionCreateInput");
        descripcionCreateInputMessage.setDisplay("icon");
        htmlPanelGrid.getChildren().add(descripcionCreateInputMessage);
        
            
        return htmlPanelGrid;
    }

	public HtmlPanelGrid populateEditPanel() {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        Application application = facesContext.getApplication();
        ExpressionFactory expressionFactory = application.getExpressionFactory();
        ELContext elContext = facesContext.getELContext();
        
        HtmlPanelGrid htmlPanelGrid = (HtmlPanelGrid) application.createComponent(HtmlPanelGrid.COMPONENT_TYPE);
        
        
        
        HtmlOutputText padreEditOutput = (HtmlOutputText) application.createComponent(HtmlOutputText.COMPONENT_TYPE);
        padreEditOutput.setId("padreEditOutput");
        padreEditOutput.setValue("Padre:   ");
        htmlPanelGrid.getChildren().add(padreEditOutput);
        
        AutoComplete padreEditInput = (AutoComplete) application.createComponent(AutoComplete.COMPONENT_TYPE);
        padreEditInput.setId("padreEditInput");
        padreEditInput.setValueExpression("value", expressionFactory.createValueExpression(elContext, "#{categoriaBean.categoria.padre}", Categoria.class));
        padreEditInput.setCompleteMethod(expressionFactory.createMethodExpression(elContext, "#{categoriaBean.completePadre}", List.class, new Class[] { String.class }));
        padreEditInput.setDropdown(true);
        padreEditInput.setValueExpression("var", expressionFactory.createValueExpression(elContext, "padre", String.class));
        padreEditInput.setValueExpression("itemLabel", expressionFactory.createValueExpression(elContext, "#{padre.nombre} #{padre.descripcion}", String.class));
        padreEditInput.setValueExpression("itemValue", expressionFactory.createValueExpression(elContext, "#{padre}", Categoria.class));
        padreEditInput.setConverter(new CategoriaConverter());
        padreEditInput.setRequired(false);
        htmlPanelGrid.getChildren().add(padreEditInput);
        
        Message padreEditInputMessage = (Message) application.createComponent(Message.COMPONENT_TYPE);
        padreEditInputMessage.setId("padreEditInputMessage");
        padreEditInputMessage.setFor("padreEditInput");
        padreEditInputMessage.setDisplay("icon");
        htmlPanelGrid.getChildren().add(padreEditInputMessage);
        
        HtmlOutputText nombreEditOutput = (HtmlOutputText) application.createComponent(HtmlOutputText.COMPONENT_TYPE);
        nombreEditOutput.setId("nombreEditOutput");
        nombreEditOutput.setValue("Nombre: * ");
        htmlPanelGrid.getChildren().add(nombreEditOutput);
        
        InputText nombreEditInput = (InputText) application.createComponent(InputText.COMPONENT_TYPE);
        nombreEditInput.setId("nombreEditInput");
        nombreEditInput.setValueExpression("value", expressionFactory.createValueExpression(elContext, "#{categoriaBean.categoria.nombre}", String.class));
        LengthValidator nombreEditInputValidator = new LengthValidator();
        nombreEditInputValidator.setMaximum(20);
        nombreEditInput.addValidator(nombreEditInputValidator);
        nombreEditInput.setRequired(true);
        htmlPanelGrid.getChildren().add(nombreEditInput);
        
        Message nombreEditInputMessage = (Message) application.createComponent(Message.COMPONENT_TYPE);
        nombreEditInputMessage.setId("nombreEditInputMessage");
        nombreEditInputMessage.setFor("nombreEditInput");
        nombreEditInputMessage.setDisplay("icon");
        htmlPanelGrid.getChildren().add(nombreEditInputMessage);
        
        HtmlOutputText descripcionEditOutput = (HtmlOutputText) application.createComponent(HtmlOutputText.COMPONENT_TYPE);
        descripcionEditOutput.setId("descripcionEditOutput");
        descripcionEditOutput.setValue("Descripcion: * ");
        htmlPanelGrid.getChildren().add(descripcionEditOutput);
        
        InputTextarea descripcionEditInput = (InputTextarea) application.createComponent(InputTextarea.COMPONENT_TYPE);
        descripcionEditInput.setId("descripcionEditInput");
        descripcionEditInput.setValueExpression("value", expressionFactory.createValueExpression(elContext, "#{categoriaBean.categoria.descripcion}", String.class));
        LengthValidator descripcionEditInputValidator = new LengthValidator();
        descripcionEditInputValidator.setMaximum(100);
        descripcionEditInput.addValidator(descripcionEditInputValidator);
        descripcionEditInput.setRequired(true);
        htmlPanelGrid.getChildren().add(descripcionEditInput);
        
        Message descripcionEditInputMessage = (Message) application.createComponent(Message.COMPONENT_TYPE);
        descripcionEditInputMessage.setId("descripcionEditInputMessage");
        descripcionEditInputMessage.setFor("descripcionEditInput");
        descripcionEditInputMessage.setDisplay("icon");
        htmlPanelGrid.getChildren().add(descripcionEditInputMessage);
       
        
        return htmlPanelGrid;
    }

	public HtmlPanelGrid populateViewPanel() {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        Application application = facesContext.getApplication();
        ExpressionFactory expressionFactory = application.getExpressionFactory();
        ELContext elContext = facesContext.getELContext();
        
        HtmlPanelGrid htmlPanelGrid = (HtmlPanelGrid) application.createComponent(HtmlPanelGrid.COMPONENT_TYPE);
        
        
        
        HtmlOutputText padreLabel = (HtmlOutputText) application.createComponent(HtmlOutputText.COMPONENT_TYPE);
        padreLabel.setId("padreLabel");
        padreLabel.setValue("Padre:   ");
        htmlPanelGrid.getChildren().add(padreLabel);
        
        HtmlOutputText padreValue = (HtmlOutputText) application.createComponent(HtmlOutputText.COMPONENT_TYPE);
        padreValue.setValueExpression("value", expressionFactory.createValueExpression(elContext, "#{categoriaBean.categoria.padre}", Categoria.class));
        padreValue.setConverter(new CategoriaConverter());
        htmlPanelGrid.getChildren().add(padreValue);
        
        HtmlOutputText nombreLabel = (HtmlOutputText) application.createComponent(HtmlOutputText.COMPONENT_TYPE);
        nombreLabel.setId("nombreLabel");
        nombreLabel.setValue("Nombre:   ");
        htmlPanelGrid.getChildren().add(nombreLabel);
        
        HtmlOutputText nombreValue = (HtmlOutputText) application.createComponent(HtmlOutputText.COMPONENT_TYPE);
        nombreValue.setId("nombreValue");
        nombreValue.setValueExpression("value", expressionFactory.createValueExpression(elContext, "#{categoriaBean.categoria.nombre}", String.class));
        htmlPanelGrid.getChildren().add(nombreValue);
        
        HtmlOutputText descripcionLabel = (HtmlOutputText) application.createComponent(HtmlOutputText.COMPONENT_TYPE);
        descripcionLabel.setId("descripcionLabel");
        descripcionLabel.setValue("Descripcion:   ");
        htmlPanelGrid.getChildren().add(descripcionLabel);
        
        InputTextarea descripcionValue = (InputTextarea) application.createComponent(InputTextarea.COMPONENT_TYPE);
        descripcionValue.setId("descripcionValue");
        descripcionValue.setValueExpression("value", expressionFactory.createValueExpression(elContext, "#{categoriaBean.categoria.descripcion}", String.class));
        descripcionValue.setReadonly(true);
        descripcionValue.setDisabled(true);
        htmlPanelGrid.getChildren().add(descripcionValue);
        
      
        
        
        return htmlPanelGrid;
    }

	public Categoria getCategoria() {
        if (categoria == null) {
            categoria = new Categoria();
        }
        return categoria;
    }

	public void setCategoria(Categoria categoria) {
        this.categoria = categoria;
    }

	public List<Publicacion> getSelectedPublicacions() {
        return selectedPublicacions;
    }

	public void setSelectedPublicacions(List<Publicacion> selectedPublicacions) {
        if (selectedPublicacions != null) {
            categoria.setPublicacions(new HashSet<Publicacion>(selectedPublicacions));
        }
        this.selectedPublicacions = selectedPublicacions;
    }

	public List<Categoria> completePadre(String query) {
        List<Categoria> suggestions = new ArrayList<Categoria>();
        for (Categoria categoria : categoriaService.findAllCategorias()) {
            String categoriaStr = String.valueOf(categoria.getNombre() +  " "  + categoria.getDescripcion());
            if (categoriaStr.toLowerCase().startsWith(query.toLowerCase())) {
                suggestions.add(categoria);
            }
        }
        return suggestions;
    }

	public List<Categoria> getSelectedCategorias() {
        return selectedCategorias;
    }

	public void setSelectedCategorias(List<Categoria> selectedCategorias) {
        if (selectedCategorias != null) {
            categoria.setCategorias(new HashSet<Categoria>(selectedCategorias));
        }
        this.selectedCategorias = selectedCategorias;
    }

	public String onEdit() {
        if (categoria != null && categoria.getPublicacions() != null) {
            selectedPublicacions = new ArrayList<Publicacion>(categoria.getPublicacions());
        }
        if (categoria != null && categoria.getCategorias() != null) {
            selectedCategorias = new ArrayList<Categoria>(categoria.getCategorias());
        }
        return null;
    }

	public boolean isCreateDialogVisible() {
        return createDialogVisible;
    }

	public void setCreateDialogVisible(boolean createDialogVisible) {
        this.createDialogVisible = createDialogVisible;
    }

	public String displayList() {
        createDialogVisible = false;
        findAllCategorias();
        return "categoria";
    }

	public String displayCreateDialog() {
        categoria = new Categoria();
        createDialogVisible = true;
        return "categoria";
    }

	public String persist() {
        String message = "";
        if (categoria.getCodigo() != null) {
            categoriaService.updateCategoria(categoria);
            message = "Successfully updated";
        } else {
            categoriaService.saveCategoria(categoria);
            message = "Successfully created";
        }
        RequestContext context = RequestContext.getCurrentInstance();
        context.execute("createDialog.hide()");
        context.execute("editDialog.hide()");
        
        FacesMessage facesMessage = new FacesMessage(message);
        FacesContext.getCurrentInstance().addMessage(null, facesMessage);
        reset();
        return findAllCategorias();
    }

	public String delete() {
        categoriaService.deleteCategoria(categoria);
        FacesMessage facesMessage = new FacesMessage("Successfully deleted");
        FacesContext.getCurrentInstance().addMessage(null, facesMessage);
        reset();
        return findAllCategorias();
    }

	public void reset() {
        categoria = null;
        selectedPublicacions = null;
        selectedCategorias = null;
        createDialogVisible = false;
    }

	public void handleDialogClose(CloseEvent event) {
        reset();
    }
}
